package com.itfreer.arcgis.gps;

import android.app.Activity;
import android.content.pm.PackageManager;
import android.graphics.Color;
import android.support.v4.app.ActivityCompat;
import android.support.v4.content.ContextCompat;

import com.esri.arcgisruntime.geometry.Point;
import com.esri.arcgisruntime.mapping.Viewpoint;
import com.esri.arcgisruntime.mapping.view.Graphic;
import com.esri.arcgisruntime.mapping.view.GraphicsOverlay;
import com.esri.arcgisruntime.mapping.view.LocationDisplay;
import com.esri.arcgisruntime.mapping.view.MapView;
import com.esri.arcgisruntime.symbology.SimpleMarkerSymbol;
import com.itfreer.arcgis.symbol.SymbolStyleType;
import com.itfreer.arcgis.symbol.SymbolUtils;
import com.itfreer.utils.common.ColorUtils;
import com.itfreer.utils.common.RequestPermissionsUtils;

import java.util.ArrayList;
import java.util.List;

/**
 * 定义基于arcgis的gps操作类
 */
public class GpsOption {
    public static final GpsOption instance = new GpsOption();

    private GpsOption() { }

    // GPS定位相关
    private LocationDisplay locationDisplay = null;
    private GraphicsOverlay graphicsOverlay_1 = null;
    private MapView mapView = null;
    private int gpsFilter = 0;

    private GPSAccuracyListener gpsAccuracyListener;
    public void setGpsAccuracyListener(GPSAccuracyListener gpsAccuracyListener) {
        this.gpsAccuracyListener = gpsAccuracyListener;
    }

    private GPSStopListener gpsStopListener;
    public void setGpsStopListener(GPSStopListener gpsStopListener) {
        this.gpsStopListener = gpsStopListener;
    }

    private List<GPSLocationListener> listeners = new ArrayList<>();
    public List<GPSLocationListener> getListeners() {
        return listeners;
    }

    /**
     * 开启gps
     *
     * @param mMapView
     */
    public void openGPS(final MapView mMapView) {
        this.mapView = mMapView;
        gpsFilter = 0;

        if (locationDisplay != null) {
            if (!locationDisplay.isStarted()) {
                locationDisplay.setAutoPanMode(LocationDisplay.AutoPanMode.OFF);
                locationDisplay.startAsync();
            }
        } else {
            locationDisplay = mMapView.getLocationDisplay();
            locationDisplay.setShowLocation(false);// 隐藏符号
            locationDisplay.setShowPingAnimation(false); // 隐藏位置更新的符号动画
            locationDisplay.setShowAccuracy(false); // 隐藏符号的缓存区域
            locationDisplay.setAutoPanMode(LocationDisplay.AutoPanMode.OFF);
            if (!locationDisplay.isStarted()) {
                locationDisplay.startAsync();
            }
            locationDisplay.addDataSourceStatusChangedListener(new LocationDisplay.DataSourceStatusChangedListener() {
                @Override
                public void onStatusChanged(LocationDisplay.DataSourceStatusChangedEvent dataSourceStatusChangedEvent) {
                    if (dataSourceStatusChangedEvent.isStarted()) {
                        return;
                    }
                    if (dataSourceStatusChangedEvent.getError() == null) {
                        return;
                    }
                    boolean permissionCheck1 = ContextCompat.checkSelfPermission(mMapView.getContext(),
                            RequestPermissionsUtils.reqPermission[2]) == PackageManager.PERMISSION_GRANTED;
                    boolean permissionCheck2 = ContextCompat.checkSelfPermission(mMapView.getContext(),
                            RequestPermissionsUtils.reqPermission[3]) == PackageManager.PERMISSION_GRANTED;

                    if (!(permissionCheck1 && permissionCheck2)) {
                        ActivityCompat.requestPermissions((Activity) mMapView.getContext(),
                                RequestPermissionsUtils.reqPermission, RequestPermissionsUtils.OPEN_GPS);
                    } else {
                        locationDisplay = null;
                    }
                }
            });

            locationDisplay.addLocationChangedListener(new LocationDisplay.LocationChangedListener() {
                @Override
                public void onLocationChanged(LocationDisplay.LocationChangedEvent locationChangedEvent) {
                    // 为有稳定性，GPS前3个点不取
                    gpsFilter ++;
                    if(gpsFilter<=3){
                        return;
                    }

                    Point point = locationChangedEvent.getLocation().getPosition();
                    // 测试数据：六约(地铁站) 114.17567567052991, 22.637088786284995
//                    Double x = 114.17567567052991;
//                    Double y = 22.637088786284995;
                    // 绘制点坐标
                    drawGpsPoint(mMapView, point);

                    double accuracy = locationChangedEvent.getLocation().getHorizontalAccuracy();
                    accuracy = (double)Math.round(accuracy*100)/100d; // 2位小数
                    if(gpsAccuracyListener!=null){
                        gpsAccuracyListener.accuracyUpdate(accuracy);
                    }
                    // 精度大于10米时，不处理后续事件
                    if(accuracy > 15){
                        return;
                    }

                    if(listeners==null || listeners.size()<=0){
                        return;
                    }

                    try {
                        for (Integer i = 0; i < listeners.size(); i++) {
                            if (listeners.get(i) != null) {
                                listeners.get(i).locationUpdate(point);
                            }
                        }
                    } catch (Exception e) {
                        e.printStackTrace();
                    }
                }
            });
        }
    }

    /**
     * 绘制gps 坐标点
     *
     * @param mapView
     * @param point
     *            gps点
     */
    private void drawGpsPoint(MapView mapView, Point point) {
        if (graphicsOverlay_1 == null) {
            graphicsOverlay_1 = new GraphicsOverlay();
        }
        graphicsOverlay_1.getGraphics().clear();
        SimpleMarkerSymbol pointSymbol = new SimpleMarkerSymbol(SimpleMarkerSymbol.Style.CIRCLE,
                ColorUtils.Hex2Int("#0099cc"), 15);
        pointSymbol.setOutline(SymbolUtils.GetPolylineSymbol(SymbolStyleType.PolylineType.SOLID, Color.WHITE, 3));
        Graphic pointGraphic = new Graphic(point, pointSymbol);
        graphicsOverlay_1.getGraphics().add(pointGraphic);

        if (!mapView.getGraphicsOverlays().contains(graphicsOverlay_1)) {
            mapView.getGraphicsOverlays().add(graphicsOverlay_1);
        }
        mapView.setViewpointAsync(new Viewpoint(point, mapView.getMapScale()));
    }

    /**
     * 关闭gps
     */
    public void stopGPS() {
        if (locationDisplay != null) {
            locationDisplay.stop();
        }

        // 清除坐标点
        if (this.mapView != null && this.graphicsOverlay_1 != null
                && this.mapView.getGraphicsOverlays().contains(graphicsOverlay_1)) {
            this.mapView.getGraphicsOverlays().remove(graphicsOverlay_1);
        }
        graphicsOverlay_1 = null;

        if(gpsStopListener!=null){
            gpsStopListener.stop();
        }
    }
}